package org.geotools.tutorial.quickstart.Utilities;

import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.util.NullProgressListener;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author
 * @DesktopJavaDocable disable
 */
public class FeatureSourceTableModel extends AbstractTableModel {
	private static final long serialVersionUID = -7119885084300393935L;
	private SimpleFeatureType schema;
	List<Object[]> cache = new ArrayList();
	public IOException exception;
	FeatureSourceTableModel.TableWorker load;

	public FeatureSourceTableModel(SimpleFeatureCollection features) {
		this.load = new FeatureSourceTableModel.TableWorker(features);
		this.load.execute();
		this.schema = (SimpleFeatureType) features.getSchema();
	}

	public void dispose() {
		this.load.cancel(false);
	}

	public String getColumnName(int column) {
		return column == 0 ? "FeatureIdentifer" : this.schema.getDescriptor(column - 1).getLocalName();
	}

	public int getColumnCount() {
		return this.exception != null ? 1 : this.schema.getAttributeCount() + 1;
	}

	public int getRowCount() {
		return this.exception != null ? 1 : this.cache.size();
	}

	public Object getValueAt(int rowIndex, int columnIndex) {
		if (rowIndex < this.cache.size()) {
			Object[] row = (Object[]) this.cache.get(rowIndex);
			return row[columnIndex];
		} else {
			return null;
		}
	}

	class TableWorker extends SwingWorker<List<Object[]>, Object[]> {
		SimpleFeatureCollection features;

		TableWorker(SimpleFeatureCollection features) {
			this.features = features;
		}

		public List<Object[]> doInBackground() {
			List<Object[]> list = new ArrayList();
			final NullProgressListener listener = new NullProgressListener();

			try {
				this.features.accepts(new FeatureVisitor() {
					public void visit(Feature feature) {
						SimpleFeature simple = (SimpleFeature) feature;
						Object[] values = simple.getAttributes().toArray();
						ArrayList<Object> row = new ArrayList(Arrays.asList(values));
						row.add(0, simple.getID());
						FeatureSourceTableModel.TableWorker.this.publish(new Object[][]{row.toArray()});
						if (FeatureSourceTableModel.TableWorker.this.isCancelled()) {
							listener.setCanceled(true);
						}

					}
				}, listener);
			} catch (IOException var4) {
				FeatureSourceTableModel.this.exception = var4;
			}

			return list;
		}

		protected void process(List<Object[]> chunks) {
			int from = FeatureSourceTableModel.this.cache.size();
			FeatureSourceTableModel.this.cache.addAll(chunks);
			int to = FeatureSourceTableModel.this.cache.size();
			FeatureSourceTableModel.this.fireTableRowsInserted(from, to);
		}
	}
}
